import turtle
import math
import random


class Spiro:
    # 初始化程序,初始化Spiro类变量中的值
    def __init__(self, R, r, l, num, color):
        self.R = R  # 大圆半径
        self.r = r  # 小圆半径
        self.l = l  # 画笔到小圆圆心的距离与小圆半径之比
        self.num = num
        self.pen = turtle.Turtle()
        self.pen.pencolor(color)
        turtle.colormode(1.0)

    def drawSingleSpiro(self):
        # 周期数 p
        p = self.periods()
        for i in range(0, 360*p + 2, 2):
            if i != 0:
                self.pen.setpos(*self.cor_x_y_Spiro(i))
            else:
                self.pen.up()
                self.pen.setpos(*self.cor_x_y_Spiro(i))
                self.pen.down()

    def drawWhole(self):
        # for s in range(self.num):
        #     if s != 0:
        #         self.randomSetting()
        #         self.drawSingleSpiro()
        #     else:
                self.drawSingleSpiro()

    def randomSetting(self):
        self.l = random.random()
        r = random.random()
        g = random.random()
        b = random.random()
        self.pen.pencolor((r, g, b))

    # 辗转相除求最大公约数
    def hcf(self, x, y):
        if x == y:
            result = x
        elif x > y:
            result = self.hcf(x-y, y)
        else:
            result = self.hcf(x, y-x)
        return result
        
    def periods(self):
        div = self.hcf(self.R, self.r)
        return self.r//div

    def cor_x_y_Spiro(self, theta):
            k = self.r/self.R
            ef = 1 - k
            rad = self.degreeToRadian(theta)
            x = self.R*(ef*math.cos(rad) + self.l*k*math.cos(ef/k*rad))
            y = self.R*(ef*math.sin(rad) - self.l*k*math.sin(ef/k*rad))
            return (x, y)
    def degreeToRadian(self, degree):
        return degree * math.pi / 180


s = Spiro(300, 210, 1, 1, "pink")
s.drawWhole()
turtle.mainloop()